﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Microsoft.Practices.Unity;
using myOSity.API;
using myOSity.API.Interop;
using XamlaApp.Model;
using XamlaApp.ViewModels;
using myOSity.API.IO;
namespace XamlaApp
{
    // ReSharper disable RedundantExtendsListEntry
    public partial class XamlaMainPage : UserControl
    // ReSharper restore RedundantExtendsListEntry
    {
        private MainUIViewModel _vm;
        private const string XamlaFileFilter = "Xamla Project Files (*.xam)|*.xam";
        [Dependency]
        public MainUIViewModel VM
        {
            get { return _vm; }
            set
            {
                _vm = value;
                DataContext = VM;
            }
        }

        public XamlaMainPage()
        {
            InitializeComponent();

            //code behind: element-to-element databinding!
            //string result = xs.GenerateXaml(this);
            //Binding b = new Binding();
            //b.Source = tbMyText;
            //b.Path = new PropertyPath("Text");
            //btnMyButton.SetBinding(ContentControl.ContentProperty, b);
            //tbMyText.Text = "Hello World!";    
            Loaded += XamlaMainPage_Loaded;
        }

        void XamlaMainPage_Loaded(object sender, RoutedEventArgs e)
        {
            //register keyboard events, depending on where the application is running (myOSity or standalone)
            var xm = Container.AppContainer.Resolve<XamlaModel>();
            if (!MoRuntimeAPI.RunningInmyOSity)
            {
                KeyUp += xm.XamlaStage_KeyUp;
                KeyDown += xm.XamlaStage_KeyDown;
            }
            else
            {
                //applications running in myosity must use these events in order to reliably receive keypress events 
                xm.MoApi.WindowKeyDown += xm.ApiWindowKeyDown;
                xm.MoApi.WindowKeyUp += xm.ApiWindowKeyUp;
            }

        }

        private void btnDeleteActiveElement_Click(object sender, RoutedEventArgs e)
        {
            VM.DeleteCurrentElement();
        }

        private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var lb = (ListBox)sender;
            var si = (ElementInfo)lb.SelectedItem;
            if (si != null)
                VM.CurrentElement = (UserControl)si.ObjectReference;
        }

        private void btnPaste_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();
            xm.DoPaste();
        }

        private void btnCopy_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();
            xm.DoCopy();
        }

        private void btnCut_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();
            xm.DoCut();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();

            if (MoRuntimeAPI.RunningInmyOSity)
            {
                var ms = xm.SaveProject();
                var s = new MemoryStream();
                s.Write(ms, 0, ms.Length);
                s.Position = 0;
                var nsfd = new MoSaveFileDialog(xm.MoApi, s, "xam", XamlaFileFilter);
                nsfd.SaveFileCompleted += (sender1, args1) =>
                                              {
                                                  if (args1.StatusCode == FileIOStatusCodes.ExceptionOccurred)
                                                  {
                                                      MessageBox.Show("An error occurred while trying to save the file.", "Xamla - Error Saving File", MessageBoxButton.OK);
                                                  }
                                                  if (args1.StatusCode == FileIOStatusCodes.Succeeded)
                                                  {
                                                      MessageBox.Show("File saved.","Success", MessageBoxButton.OK);
                                                  }
                                                  s.Close();
                                              };
                nsfd.ShowDialog();
            }
            else
            {
                var sfd = new SaveFileDialog { Filter = XamlaFileFilter };

                if (!((bool)sfd.ShowDialog())) return;

                var ms = xm.SaveProject();
                using (var s = sfd.OpenFile())
                {
                    s.Write(ms, 0, Convert.ToInt32(ms.Length));
                    s.Close();
                }
            }
        }

        private void btnLoad_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();

            if (MoRuntimeAPI.RunningInmyOSity)
            {
                //app is running in myOSity so use the myOSity API to show the open file dialog.
                //this allows the user to access their files on the myOSity file system, or their local computer.
                var nofd = new MoOpenFileDialog(xm.MoApi, false, "xam", XamlaFileFilter);
                nofd.OpenFileCompleted += MoOpenFileCompleted;
                nofd.ShowDialog();
            }
            else
            {
                //app is not running in myOSity so just show the standard dialog for local computer access.
                var ofd = new OpenFileDialog { Filter = XamlaFileFilter, Multiselect = false };
                if (!((bool)ofd.ShowDialog())) return;

                var b = new byte[ofd.File.Length];
                using (Stream s = ofd.File.OpenRead())
                {
                    s.Read(b, 0, b.Length);
                    xm.LoadProject(b);
                    s.Close();
                }
            }
        }

        private static void MoOpenFileCompleted(object sender, OpenFileEventArgs e)
        {
            if (e.StatusCode == FileIOStatusCodes.ExceptionOccurred)
            {
                MessageBox.Show("An error occurred while trying to load the file.", "Xamla - Error Loading File", MessageBoxButton.OK);
                return;
            }
            if (e.StatusCode == FileIOStatusCodes.UserCancelled) return;

            var fileStream = e.Files.First();
            var b = new byte[fileStream.FileStream.Length];
            using (var s = fileStream.FileStream)
            {
                s.Read(b, 0, b.Length);
                var xm = Container.AppContainer.Resolve<XamlaModel>();
                xm.LoadProject(b);
                s.Close();
            }
        }

        private void btnNew_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();
            xm.InitializeApplication();
        }

        private void btnExportXaml_Click(object sender, RoutedEventArgs e)
        {
            var sfd = new SaveFileDialog
                          {
                              Filter = "Xaml Files (.xaml)|*.xaml"
                          };

            var generatedXaml = VM.GenerateXaml();

            if ((bool)sfd.ShowDialog())
            {
                var uni = new UnicodeEncoding();
                var ms = uni.GetBytes(generatedXaml);
                using (var s = sfd.OpenFile())
                {
                    s.Write(ms, 0, Convert.ToInt32(ms.Length));
                    s.Close();
                }
            }
        }

        private void btnExportToImageViewer_Click(object sender, RoutedEventArgs e)
        {
            var xm = Container.AppContainer.Resolve<XamlaModel>();
            var wbm = new WriteableBitmap(xm.VM.StageView, null);
            xm.MoApi.SendInteropMessage(new InteropMessage(MyOSityImplementation.InteropName, MyOSityImplementation.ImageViewerInteropName, "loadimage", new List<object> { wbm }));
        }
    }
}
